package com.yunjian.core.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunjian.common.utils.*;
import com.yunjian.core.dto.*;
import com.yunjian.core.entity.*;
import com.yunjian.core.mapper.PurchaseOrderMapper;
import com.yunjian.core.service.*;
import com.yunjian.core.vo.PurchaseOrderVo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 采购订单信息表 服务实现类
 * </p>
 *
 * @author xiapengyu
 * @since 2020-02-18
 */
@Service
public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements IPurchaseOrderService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IPurchaseDetailService purchaseDetailService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IGoodsImgService goodsImgService;
    @Autowired
    private IGoodsCartService goodsCartService;
    @Autowired
    private IGoodsTypeService goodsTypeService;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private IAccountService accountService;

    @Resource
    private PurchaseOrderMapper purchaseOrderMapper;

    @Override
    public R updateStatus(Map<String, Object> params) {
        int id = (int) params.get("id");
        int status = (int) params.get("status");
        String comment = (String) params.get("comment");
        PurchaseOrder order = new PurchaseOrder();
        order.setId(id);
        order.setStatus(status);
        order.setComment(comment);
        UpdateWrapper<PurchaseOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.set("status", status);
        boolean b = update(order, updateWrapper);

        R r = R.ok();
        if (b) {
            r.put("success", "success");
        } else {
            r.put("success", "error");
        }

        return r;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String orderNo = StringUtil.obj2String(params.get("orderNo"));
        String email = StringUtil.obj2String(params.get("email"));
        Integer isAdmin = Integer.parseInt(params.get("isAdmin").toString());
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<PurchaseOrder>();
        if(StringUtils.isNotBlank(orderNo)){
            queryWrapper.like("order_no", orderNo);
        }
        if(StringUtils.isNotBlank(email)){
            queryWrapper.like("email", email);
        }
        //非管理员查询全部订单
        if(isAdmin.intValue() == 0){
            queryWrapper.like("dealer_id", HttpContextUtils.getLoginSysUserEntity().getUserId().intValue());
        }
        queryWrapper.eq("delete_flag", 1).orderByDesc("create_time");
        IPage<PurchaseOrder> page = this.page(new Query<PurchaseOrder>().getPage(params), queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public ResponseDto submitCart(OrderReqDto param) {
        ResponseDto response = new ResponseDto(Constant.SUCCESS_CODE, null, Constant.SUCCESS_MESSAGE);
        try {
            Account cacheAccount = SecurityContext.getUserPrincipal();
            Account account = accountService.getOne(new QueryWrapper<Account>().eq("id", cacheAccount.getId()));
            PurchaseOrder order = new PurchaseOrder();
            order.setOrderNo(BusinessUtils.createOrderNo());
            order.setRemark(param.getComment());
            order.setAccountId(account.getId());
            Address address = addressService.getOne(new QueryWrapper<Address>().eq("id", param.getAddressId()));
            order.setAddressId(param.getAddressId());
            order.setUserName(address.getUserName());
            order.setPhone(address.getPhone());
            order.setAddress(address.getAddress());
            order.setStatus(1);
            order.setCreateTime(new Date());
            order.setUpdateTime(new Date());
            order.setDeleteFlag(1);
            order.setDealerId(account.getDealerId());
            SysUserEntity sysUser = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("user_id", account.getDealerId()));
            order.setDealerName(sysUser.getUsername());
            order.setPayAccount(sysUser.getBankAccount());
            this.saveOrUpdate(order);

            List<PurchaseDetail> detailList = new ArrayList<>();
            List<CartGoodsAmountDto> goodsList = param.getGoodsList();
            for (CartGoodsAmountDto item : goodsList) {
                GoodsCart goodsCart = goodsCartService.getOne(new QueryWrapper<GoodsCart>().eq("account_id", account.getId()).eq("goods_id", item.getGoodsId()));
                if (goodsCart == null) {
                    continue;
                }

                PurchaseDetail detail = new PurchaseDetail();
                detail.setGoodsId(item.getGoodsId());
                Goods goods = goodsService.getOne(new QueryWrapper<Goods>().eq("id", item.getGoodsId()));
                detail.setAmount(item.getAmount());
                detail.setGoodsName(goods.getName());
                detail.setOrderNo(order.getOrderNo());
                detail.setUnitPrice((goods.getIsDiscount() == 1) ? goods.getDiscountPrice() : goods.getPrice());
                detail.setPrice(detail.getUnitPrice().multiply(BigDecimal.valueOf(detail.getAmount().doubleValue())));
                detail.setGoodsKind(goods.getKind());
                detail.setGoodsType(org.springframework.util.StringUtils.isEmpty(goods.getType()) ? 0 : Integer.parseInt(goods.getType()));
                detailList.add(detail);
            }
            if (!detailList.isEmpty()) {
                logger.info("保存采购清单信息{}", detailList);
                purchaseDetailService.saveBatch(detailList);
                //提交成功之后清空购物车
                goodsCartService.remove(new QueryWrapper<GoodsCart>().eq("account_id", account.getId()));
            } else {
                this.remove(new QueryWrapper<PurchaseOrder>().eq("id", order.getId()));
                return new ResponseDto(Constant.FAIL_CODE, null, LanguageUtils.getValueByKey("goodsCart.no.goods"));
            }
        } catch (Exception e) {
            logger.error("提交采购单失败", e);
            return new ResponseDto(Constant.FAIL_CODE, null, LanguageUtils.getValueByKey("goodsCart.submit.fail"));
        }
        return response;
    }

    @Override
    public PageUtils queryOrderByPage(Map<String, Object> params) {
        Account account = SecurityContext.getUserPrincipal();
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<PurchaseOrder>();
        queryWrapper.eq("account_id", account.getId())
                .eq("delete_flag", 1)
                .orderByDesc("create_time");
        IPage<PurchaseOrder> page = this.page(new Query<PurchaseOrder>().getPage(params), queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryOrderByPage4Sys(Map<String, Object> map) {
        long pageSize = Long.parseLong(map.get("limit").toString());
        long currentPage = Long.parseLong(map.get("currPage").toString());
        Page<PurchaseOrderVo> page = new Page<>(currentPage, pageSize);
        logger.info("分页请求参数{}", JsonUtil.toJsonString(map));
        IPage<PurchaseOrderVo> pageResult = purchaseOrderMapper.selectPageVoOfAppUser(page, map);
        return new PageUtils(pageResult);
    }

    @Override
    public ResponseDto queryOrderDetail(String orderNo) {
        ResponseDto response = new ResponseDto(Constant.SUCCESS_CODE, null, Constant.SUCCESS_MESSAGE);
        try {
            PurchaseOrder order = this.getOne(new QueryWrapper<PurchaseOrder>().eq("order_no", orderNo));
            OrderRespDto dto = new OrderRespDto();
            BeanUtils.copyProperties(order, dto);
            BigDecimal totalPrice = BigDecimal.ZERO;
            List<GoodsCartInfo> goodsList = new ArrayList<>();
            List<PurchaseDetail> detailList = purchaseDetailService.list(new QueryWrapper<PurchaseDetail>().eq("order_no", orderNo));
            for (PurchaseDetail item : detailList) {
                GoodsCartInfo info = new GoodsCartInfo();
                Goods goods = goodsService.getOne(new QueryWrapper<Goods>().eq("id", item.getGoodsId()));
                info.setId(item.getId());
                info.setGoodsId(goods.getId());
                info.setName(goods.getName());
                info.setAmount(item.getAmount());
                info.setUnitPrice(item.getUnitPrice());
                info.setTotalPrice(item.getPrice());
                totalPrice = totalPrice.add(item.getUnitPrice().multiply(BigDecimal.valueOf(info.getAmount().doubleValue())));
                info.setGoodsType(item.getGoodsType());
                info.setGoodsKind(item.getGoodsKind());
                /*GoodsType type = goodsTypeService.getOne(new QueryWrapper<GoodsType>().eq("id", item.getGoodsType()));
                if (type != null) {
                    info.setGoodsTypeName(type.getTypeName());
                }*/
                List<GoodsImg> imgList = goodsImgService.list(
                        new QueryWrapper<GoodsImg>()
                                .eq("goods_id", item.getGoodsId()).orderByAsc("create_time"));
                if (!imgList.isEmpty()) {
                    info.setCoverImg(imgList.get(0).getImageUrl());
                }
                goodsList.add(info);
            }
            dto.setTotalPrice(totalPrice);
            dto.setGoodsList(goodsList);
            response.setData(dto);
        } catch (BeansException e) {
            logger.error("查看采购详情失败", e);
            return new ResponseDto(Constant.FAIL_CODE, null, LanguageUtils.getValueByKey("order.query.fail"));
        }
        return response;
    }

    @Override
    public PageUtils queryAccountOrderList(Map<String, Object> params) {
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<PurchaseOrder>();
        queryWrapper.eq("delete_flag", 1).orderByDesc("create_time");
        IPage<PurchaseOrder> page = this.page(new Query<PurchaseOrder>().getPage(params), queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public OrderRespDto queryOrderInfo(String orderNo) {
        PurchaseOrder order = this.getOne(new QueryWrapper<PurchaseOrder>().eq("order_no", orderNo));
        OrderRespDto dto = new OrderRespDto();
        BeanUtils.copyProperties(order, dto);

        List<GoodsCartInfo> goodsList = new ArrayList<>();
        List<PurchaseDetail> detailList = purchaseDetailService.list(new QueryWrapper<PurchaseDetail>().eq("order_no", orderNo));
        for (PurchaseDetail item : detailList) {
            GoodsCartInfo info = new GoodsCartInfo();
            Goods goods = goodsService.getOne(new QueryWrapper<Goods>().eq("id", item.getGoodsId()));
            info.setId(item.getGoodsId());
            info.setName(goods.getName());
            info.setAmount(item.getAmount());
            info.setUnitPrice(item.getUnitPrice());
            info.setTotalPrice(item.getPrice());
            List<GoodsImg> imgList = goodsImgService.list(
                    new QueryWrapper<GoodsImg>()
                            .eq("goods_id", item.getId()).orderByAsc("create_time"));
            if (!imgList.isEmpty()) {
                info.setCoverImg(imgList.get(0).getImageUrl());
            }
            goodsList.add(info);
        }
        dto.setGoodsList(goodsList);
        return dto;
    }

}
